﻿using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Diagnostics;
using System.Windows.Forms;
using System.Reflection;
using System.Runtime.InteropServices;
using System.IO;
//using DevExpress.XtraGrid;
using System.Security.Cryptography;
using System.Data.OleDb;
using DevExpress.XtraEditors;

namespace ERP.Classes
{
    public class csCSDL
    {
        public class DataReaderAdapter : System.Data.Common.DbDataAdapter
        {
            public int FillFromReader(DataTable dataTable, IDataReader dataReader)
            {
                return this.Fill(dataTable, dataReader);
            }
        }

        public TemplateParameter[] para;
        SqlConnection dataConnection = new SqlConnection();
        /// <summary>
        /// Procedure CMScommon()
        /// Hàm thiết lập
        /// Date 30/03/2007
        /// </summary>
        /// 
        private string ConfigFileName = Application.StartupPath + @"\config.ini";

        public csCSDL()
        {
            dataConnection.ConnectionString = "";
        }
        public string EncodePassword(string originalPassword)
        {
            //Declarations
            Byte[] originalBytes;
            Byte[] encodedBytes;
            MD5 md5;

            //Instantiate MD5CryptoServiceProvider, get bytes for original password and compute hash (encoded password)
            md5 = new MD5CryptoServiceProvider();
            originalBytes = ASCIIEncoding.Default.GetBytes(originalPassword);
            encodedBytes = md5.ComputeHash(originalBytes);

            //Convert encoded bytes back to a 'readable' string
            string ret = BitConverter.ToString(encodedBytes);
            ret = ret.Replace("-", "");
            return ret;
        }

        private bool ok = false;
        private void TestConnect()
        {
            if (ok == true) return;
            //bool ok = false;
            string strConnect = "";
            while (ok == false)
            {
                strConnect = GetConfig();
                if (strConnect == "")
                {
                    MessageBox.Show("Sai Thông Tin Máy Chủ CSDL. Hãy thiết lập lại", "Lỗi Kết Nối");
                    frmSettings f = new frmSettings();
                    if (f.ShowDialog() == DialogResult.OK)
                    {
                    }
                    else
                    {
                        ok = true;
                        Application.Exit();
                        Environment.Exit(0);
                    }
                }
                else
                {
                    dataConnection.ConnectionString = strConnect;
                    try
                    {
                        if (dataConnection.State == ConnectionState.Closed)
                        {
                            dataConnection.Open();
                        }
                        ok = true;
                    }
                    catch //(SqlException ex)
                    {
                        MessageBox.Show("Sai Thông Tin Máy Chủ CSDL. Hãy thiết lập lại");
                        frmSettings f = new frmSettings();
                        if (f.ShowDialog() == DialogResult.OK)
                        {
                        }
                        else
                        {
                            ok = true;
                            Application.Exit();
                            Environment.Exit(0);
                        }
                    }
                }
            }
        }

        private string GetConfig()
        {
            string ret = "";
            if (System.IO.File.Exists(ConfigFileName))
            {
                DataSet ds = new DataSet("Config");
                ds.ReadXml(ConfigFileName);
                if (ds != null)
                {
                    ret = "Data Source=" + ds.Tables[0].Rows[0]["SERVER"].ToString();

                    ret = ret + ";Initial Catalog=" + ds.Tables[0].Rows[0]["DATABASE"].ToString();
                    if (ds.Tables[0].Rows[0]["USERNAME"].ToString() != "")
                        ret = ret + ";User ID=" + ds.Tables[0].Rows[0]["USERNAME"].ToString();
                    if (ds.Tables[0].Rows[0]["PASSWORD"].ToString() != "")
                        ret = ret + ";Password=" + ds.Tables[0].Rows[0]["PASSWORD"].ToString();
                }
            }
            return ret;
        }

        /// <summary>c
        /// Hàm lấy giá trị kết nối database
        /// </summary>
        /// <returns></returns>
        public SqlConnection getConnection()
        {
            return this.dataConnection;
        }
        public void executeNonQueryWithTran(string sqlCommand, object[] param
           , object[] value, ref SqlConnection con, ref SqlTransaction tran)
        {

            SqlCommand command = new SqlCommand(sqlCommand);

            if (param != null)
            {
                for (int i = 0; i < param.Length; i++)
                {
                    if (value[i] != null)
                    {
                        command.Parameters.AddWithValue("@" + param[i], value[i]);
                    }
                    else
                    {
                        command.Parameters.AddWithValue("@" + param[i], System.DBNull.Value);
                    }
                }
            }
            command.CommandType = CommandType.StoredProcedure;
            command.Connection = this.dataConnection;
            command.Transaction = tran;
            command.ExecuteNonQuery();

        }

        public void executeNonQueryWithTran(string sqlCommand, ref SqlConnection con, ref SqlTransaction tran)
        {

            SqlCommand command = new SqlCommand(sqlCommand);
            command.CommandType = CommandType.Text;
            command.Connection = this.dataConnection;
            command.Transaction = tran;
            command.ExecuteNonQuery();

        }

        /// <summary>
        /// Procedure Open()
        /// Thực hiện kết nối đến SQLSERVER 2005
        /// Date 30/03/2007
        /// </summary>
        /// <returns>True-False(Thông báo lỗi nếu có)</returns>
        public Boolean open()
        {
            TestConnect();
            if (dataConnection.ConnectionString == "")
            {
                this.errorMessage(-1, "");
                return false;
            }
            try
            {
                if (dataConnection.State == ConnectionState.Closed)
                {
                    dataConnection.Open();
                }
                return true;
            }
            catch (SqlException ex)
            {
                this.errorMessage(ex.Number, ex.Message);
            }
            return false;
        }

        /// <summary>
        /// Procedure Close()
        /// Đóng kết nối đến SQLSERVER 2005
        /// Date 30/03/2007
        /// </summary>
        /// <returns>True-False(Thông báo lỗi nếu có)</returns>
        public void close()
        {
            try
            {
                if (dataConnection.State == ConnectionState.Open)
                {
                    dataConnection.Close();
                }
            }
            catch (SqlException ex)
            {
                this.errorMessage(ex.Number, ex.Message);
            }
        }

        /// <summary>
        /// Function getDataTable()
        /// Đọc dữ liệu từ SQL trả về DataTable
        /// Date 30/03/2007
        /// </summary>
        /// <param name="sqlCommand">Câu lệnh SQL</param>
        /// <returns>DataTable</returns>
        public DataTable getDataTable(string sqlCommand)
        {
            DataSet ds = this.getDataSet(sqlCommand);
            if (ds != null)
            {
                return ds.Tables[0];
            }
            return null;
        }

        /// <summary>
        /// Hàm đọc dữ liệu từ thủ tục SQL trả về DataTable có tham số
        /// </summary>
        /// <param name="StoredProcedureName">Tên thủ tục SQL</param>        
        /// <returns>DataTable</returns>
        public DataTable getDataTableStoredProcedure(object[] param, object[] value, string storedProcedureName)
        {
            DataSet ds = this.getDataSet(param, value, storedProcedureName);
            if (ds != null)
            {
                return ds.Tables[0];
            }
            return null;
        }

        /// <summary>
        /// Function getDataReader()
        /// Hàm đọc dữ liệu từ SQL trả về SqlDataReader
        /// Date 30/03/2007
        /// </summary>
        /// <param name="sqlCommand">Câu lệnh SQL</param>   
        /// <returns>SQLDataReader</returns>
        public SqlDataReader getDataReader(string sqlCommand)
        {
            if (this.open())
            {
                try
                {
                    SqlDataReader myReader;
                    SqlCommand dataCommand = new SqlCommand();
                    dataCommand.Connection = this.dataConnection;
                    dataCommand.CommandText = sqlCommand;
                    myReader = dataCommand.ExecuteReader();
                    //this.close();
                    return myReader;
                }
                catch (SqlException ex)
                {
                    this.errorMessage(ex.Number, ex.Message);
                }
            }
            return null;
        }

        /// <summary>
        /// Function getDataset()
        /// Hàm đọc dữ liệu từ SQL trả về DataSet 
        /// Date 30/03/2007
        /// </summary>
        /// <param name="sqlCommand">Câu lệnh SQL</param>
        /// /// <returns>DataSet</returns>
        public DataSet getDataSet(string sqlCommand)
        {
            if (this.open())
            {
                try
                {
                    DataSet ds = new DataSet();
                    SqlDataAdapter adp;
                    SqlCommandBuilder sqlBuilder = new SqlCommandBuilder();
                    adp = new SqlDataAdapter(sqlCommand, this.dataConnection);
                    adp.Fill(ds);
                    sqlBuilder.DataAdapter = adp;
                    this.close();
                    return ds;
                }
                catch (SqlException ex)
                {
                    MessageBox.Show(ex.Message);
                    // this.errorMessage(ex.Number);
                }
            }
            return null;
        }

        /// <summary>
        /// Hàm đọc dữ liệu từ SQL trả về DataSet có tham số truyền vào
        /// </summary>
        /// <param name="param">Mảng tham số(@,@,...) </param>
        /// <param name="value">Mảng giá trị</param>
        /// <param name="storedProcedureName">Tên thủ tục</param>
        /// <returns></returns>
        public DataSet getDataSet(object[] param, object[] value, string storedProcedureName)
        {
            if (this.open())
            {
                ////frmProcess fprocess = new frmProcess();
                ////fprocess.Show();                
                try
                {
                    DataSet ds = new DataSet();
                    SqlCommand command = new SqlCommand();
                    command.Connection = this.dataConnection;
                    if (param != null)
                    {
                        for (int i = 0; i < param.Length; i++)
                        {
                            if (value[i] != null)
                                command.Parameters.Add(new SqlParameter("@" + param[i], value[i]));
                            else
                                command.Parameters.Add(new SqlParameter("@" + param[i], System.DBNull.Value));
                        }
                    }
                    command.CommandType = CommandType.StoredProcedure;
                    command.CommandText = storedProcedureName;
                    SqlDataAdapter adp;
                    SqlCommandBuilder sqlBuilder = new SqlCommandBuilder();
                    adp = new SqlDataAdapter(command);
                    adp.Fill(ds);
                    sqlBuilder.DataAdapter = adp;
                    //fprocess.Close();
                    this.close();
                    return ds;
                }
                catch (SqlException ex)
                {
                    //fprocess.Close();                    
                    MessageBox.Show(ex.Message);
                    //this.errorMessage(ex.Number);
                }
            }
            return null;
        }

        /// <summary>
        /// Function executeScalar()
        /// Hàm truy vấn có giá trị trả về
        /// </summary>
        /// <param name="sqlCommand">Câu lệnh SQL</param>
        /// <returns>object</returns>
        public object getObject(string sqlCommand)
        {
            if (this.open())
            {
                try
                {
                    SqlCommand command = new SqlCommand(sqlCommand);
                    command.Connection = this.dataConnection;
                    command.CommandType = System.Data.CommandType.Text;
                    return command.ExecuteScalar();
                }
                catch (SqlException ex)
                {
                    this.errorMessage(ex.Number, ex.Message);
                    return null;
                }
                finally
                {
                    this.close();
                }
            }
            else return null;
        }

        /// <summary>
        /// Function executeScalar()
        /// Hàm truy vấn có giá trị trả về từ thủ tục
        /// </summary>
        /// <param name="storedProcedureName">Thủ tục SQL</param>
        /// <returns>object</returns>
        public object getObjectStoredProcedure(object[] param, object[] values, string storedProcedureName)
        {
            if (this.open())
            {
                try
                {
                    SqlCommand command = new SqlCommand(storedProcedureName);
                    command.Connection = this.dataConnection;
                    if (param != null)
                    {
                        for (int i = 0; i < param.Length; i++)
                        {
                            if (values[i] != null)
                                command.Parameters.Add(new SqlParameter("@" + param[i], values[i]));
                            else
                                command.Parameters.Add(new SqlParameter("@" + param[i], System.DBNull.Value));
                        }
                    }
                    command.CommandType = System.Data.CommandType.StoredProcedure;
                    command.CommandText = storedProcedureName;

                    return command.ExecuteScalar();

                }
                catch (SqlException ex)
                {
                    this.errorMessage(ex.Number, ex.Message);
                    return null;
                }
                finally
                {
                    this.close();
                }
            }
            return null;
        }

        /// <summary>
        /// Hàm lấy giá trị trả về sau khi cập nhật dữ liệu vào SQL
        /// </summary>
        /// <param name="sqlCommand">Câu lệnh SQL</param>
        /// <returns>object</returns>
        public object executeUpdateScalar(string sqlCommand)
        {
            if (this.open())
            {
                try
                {
                    SqlCommand command = new SqlCommand(sqlCommand);
                    command.Connection = this.dataConnection;
                    command.CommandType = System.Data.CommandType.Text;
                    command.ExecuteNonQuery();
                    command = new SqlCommand("SELECT @@IDENTITY");
                    command.Connection = this.dataConnection;
                    command.CommandType = System.Data.CommandType.Text;

                    return command.ExecuteScalar();

                }
                catch (SqlException ex)
                {
                    this.errorMessage(ex.Number, ex.Message);
                    return null;
                }
                finally
                {
                    this.close();
                }
            }
            else return null;
        }


        /// <summary>
        /// Thủ tục cập nhật dữ liệu (thêm, sửa, xoá) vào SQL
        /// </summary>
        /// <param name="sqlCommand">Câu lệnh SQL</param>
        public Boolean executeNonQuery(string sqlCommand, [Optional, DefaultParameterValue(false)] Boolean allowOpen)
        {
            if (this.open())
            {
                try
                {
                    SqlCommand command = new SqlCommand(sqlCommand);
                    command.Connection = this.dataConnection;
                    command.CommandType = System.Data.CommandType.Text;
                    command.ExecuteNonQuery();
                    if (!allowOpen)
                        this.close();
                }
                catch (SqlException ex)
                {
                    //MessageBox.Show(ex.Message);
                    this.errorMessage(ex.Number, ex.Message);
                    return false;
                }
                return true;
            }
            return false;
        }

        /// <summary>
        /// Thủ tục cập nhật dữ liệu (thêm, sửa, xoá) vào SQL từ thủ tục
        /// </summary>
        /// <param name="storedProcedureName">Thủ tục SQL</param>
        public Boolean executeNonQueryStoredProcedure(object[] param
            , object[] value
            , string storedProcedureName
            , [Optional, DefaultParameterValue(false)] Boolean allowOpen)
        {
            if (this.open())
            {
                try
                {
                    SqlCommand command = new SqlCommand();
                    command.Connection = this.dataConnection;
                    if (param != null)
                    {
                        for (int i = 0; i < param.Length; i++)
                        {
                            if (value[i] != null)
                                command.Parameters.Add(new SqlParameter("@" + param[i], value[i]));
                            else
                                command.Parameters.Add(new SqlParameter("@" + param[i], System.DBNull.Value));
                        }
                    }
                    command.CommandType = CommandType.StoredProcedure;
                    command.CommandText = storedProcedureName;
                    command.ExecuteNonQuery();
                }
                catch (SqlException ex)
                {
                    MessageBox.Show(ex.Message);
                    this.errorMessage(ex.Number, ex.Message);
                    return false;
                }
                finally
                {
                    if (!allowOpen)
                        this.close();
                }
                return true;
            }
            return false;
        }

        /// <summary>
        /// Thủ tục cập nhật dữ liệu (thêm, sửa, xoá) vào SQL từ thủ tục
        /// </summary>
        /// <param name="storedProcedureName">Thủ tục SQL</param>
        public Boolean executeNonQueryStoredProcedure(object[] param
            , object[] value, SqlDbType[] type
            , string storedProcedureName
            , [Optional, DefaultParameterValue(false)] Boolean allowOpen)
        {
            if (this.open())
            {
                try
                {
                    SqlCommand command = new SqlCommand();
                    command.Connection = this.dataConnection;
                    if (param != null)
                    {
                        for (int i = 0; i < param.Length; i++)
                        {
                            if (value[i] != null)
                            {
                                SqlParameter para = new SqlParameter("@" + param[i], value[i]);
                                para.SqlDbType = type[i];
                                command.Parameters.Add(para);
                            }
                            else
                            {
                                SqlParameter para = new SqlParameter("@" + param[i], System.DBNull.Value);
                                para.SqlDbType = type[i];
                                command.Parameters.Add(para);
                            }
                        }
                    }
                    command.CommandType = CommandType.StoredProcedure;
                    command.CommandText = storedProcedureName;
                    command.ExecuteNonQuery();

                }
                catch (SqlException ex)
                {
                    MessageBox.Show(ex.Message);
                    this.errorMessage(ex.Number, ex.Message);
                    return false;
                }
                finally
                {
                    if (!allowOpen)
                        this.close();
                }
                return true;
            }
            return false;
        }

        /// <summary>
        /// Thủ tục cập nhật trường ảnh vào SQL
        /// </summary>
        /// <param name="sqlCommand">Câu lệnh SQL</param>
        /// <param name="arrImage">Ảnh</param>
        public void executeUpdateImage(string sqlCommand, byte[] arrImage)
        {
            if (this.open())
            {
                try
                {
                    SqlCommand command = new SqlCommand(sqlCommand);
                    command.Connection = this.dataConnection;
                    command.Parameters.Add(new SqlParameter("@COMPUTER_FILE_CONTENT", SqlDbType.Image)).Value = arrImage;
                    command.ExecuteNonQuery();
                    this.close();
                }
                catch (SqlException ex)
                {
                    this.errorMessage(ex.Number, ex.Message);
                }
            }
        }

        /// <summary>
        /// Cập nhật DataSet
        /// </summary>
        /// <param name="tbname">DataTable</param>
        /// <param name="sqlCommand">Câu lệnh SQL</param>
        public bool UpdateDataset(ref DataTable tbname, string sqlCommand)
        {
            if (this.open())
            {
                try
                {
                    SqlDataAdapter adp;
                    SqlCommandBuilder sqlBuilder = new SqlCommandBuilder();
                    adp = new SqlDataAdapter(sqlCommand, this.dataConnection);
                    sqlBuilder.DataAdapter = adp;
                    adp.Update(tbname);
                    this.close();
                    return true;
                }
                catch (SqlException ex)
                {
                    this.errorMessage(ex.Number, ex.Message);
                }
            }
            return false;
        }

        /// <summary>
        /// Hàm hiển thị thông báo lỗi khi thực thi SQL
        /// </summary>
        /// <param name="eNumber">Mã lỗi</param>
        public void errorMessage(int eNumber, string eMessage)
        {
            string err = "";
            Boolean ask = true;
            switch (eNumber)
            {
                case -1:
                    err = "Lỗi - Chưa lưu thông tin máy chủ CSDL !";
                    break;
                case 208:
                    err = "Lỗi - Table hoặc View không tồn tại !";
                    break;
                case 102:
                    err = "Lỗi - Sai cú pháp !";
                    break;
                case 64:
                    err = "Lỗi - Xem lại cáp đường truyền mạng !";
                    break;
                case 547:
                    if (eMessage.IndexOf("The INSERT statement conflicted with the") >= 0)
                        err = "Lỗi - Dữ liệu được sử dụng để insert vào bảng này đã bị xóa nên không thể lưu được !";
                    else if (eMessage.IndexOf("The UPDATE statement conflicted with the") >= 0)
                        err = "Lỗi - Dữ liệu được sử dụng để update vào bảng này đã bị xóa nên không thể lưu được !";
                    else
                        err = "Lỗi - Dữ liệu đã được sử dụng ở một bảng khác nên không thể xoá !\nDữ liệu chỉ có thể được xóa khi không còn bảng nào dùng nó !";
                    ask = false;
                    break;
                case 2812:
                    err = "Lỗi - không tồn tại stored procedure !";
                    break;
                case 10054:
                    err = "Lỗi - Disable mạng !";
                    break;

                case 4060:
                    err = "Lỗi - Kết nối dữ liệu !";
                    break;

                case 53:
                    err = "Lỗi - Kết nối máy chủ CSDL !";
                    break;

                case 2627:
                    err = "Lỗi - Trùng khoá !";
                    break;

                default:
                    err = "Lỗi thực thi, xem lại stored procedure hoặc độ dài và cho phép null của các trường theo quy định!";
                    break;
            }
            if (!ask)
            {
                XtraMessageBox.Show(err, "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else if (XtraMessageBox.Show(err + "\nBạn có muốn đóng chương trình không ?", "Xác nhận", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes)
            {
                Application.Exit();
            }
        }


        public int ExcuteStoreProcedure(string procedureName)
        {
            SqlCommand command = new SqlCommand();
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = procedureName;
            command.Connection = this.dataConnection;
            int num = this.para.GetLength(0);

            for (int i = 0; i < num; i++)
            {
                SqlParameter parameter = new SqlParameter(this.para[i].ParameterName, this.para[i].Value);
                command.Parameters.Add(parameter);
            }

            int rowCount = 0;
            try
            {
                open();
                rowCount = command.ExecuteNonQuery();
                close();
                return rowCount;
            }
            //catch (Exception ex)
            //{
            //    MessageBox.Show(ex.Message);
            //    return -1;
            //}
            catch (SqlException ex)
            {
                this.errorMessage(ex.Number, ex.Message);
                return -1;
            }
        }

        public DataSet ExcuteStoreProcedure_Query(string procedureName)
        {
            SqlCommand command = new SqlCommand();
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = procedureName;
            command.Connection = this.dataConnection;
            int num = this.para.GetLength(0);

            for (int i = 0; i < num; i++)
            {
                SqlParameter parameter = new SqlParameter(this.para[i].ParameterName, this.para[i].Value);
                command.Parameters.Add(parameter);
            }

            SqlDataReader ret = null;
            try
            {
                open();
                ret = command.ExecuteReader();

                DataSet ds = new DataSet();
                DataTable dt = new DataTable();
                DataReaderAdapter da = new DataReaderAdapter();
                da.FillFromReader(dt, ret);
                ds.Tables.Add(dt);

                close();
                return ds;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return null;
            }
        }

        public int CreateParameters(string[] paraName, int numCols, object[] value)
        {
            para = new TemplateParameter[numCols];
            for (int i = 0; i < numCols; i++)
            {
                para[i] = new TemplateParameter(paraName[i], value[i]);
            }
            return 1;
        }

        public DataSet OpenTable(string tableName, string condition)
        {
            string mySQL;
            mySQL = "Select * from " + tableName;

            if (condition != "")
            {
                mySQL += " Where " + condition;
            }

            try
            {
                this.open();
                SqlDataAdapter DA = new SqlDataAdapter();
                DA.SelectCommand = new SqlCommand(mySQL, this.dataConnection);

                DataSet DSet = new DataSet("Bang");
                DA.Fill(DSet, "Dulieu");

                this.close();
                return DSet;
            }
            catch
            {
                return null;
            }
        }

        public DataSet SelecSQL(string mySQL)
        {
            try
            {
                this.open();
                SqlDataAdapter DA = new SqlDataAdapter();
                DA.SelectCommand = new SqlCommand(mySQL, this.dataConnection);

                DataSet DSet = new DataSet("Bang");
                DA.Fill(DSet, "Dulieu");

                this.close();
                return DSet;
            }
            catch
            {
                return null;
            }
        }

        public int XoaDuLieu(string condition, string table)
        {
            string mySql;
            mySql = "Delete from " + table + " Where " + condition;
            SqlCommand myCommand = new SqlCommand(mySql, this.dataConnection);

            try
            {
                this.open();
                int numRow = 0;
                numRow = myCommand.ExecuteNonQuery();
                this.close();
                return numRow;
            }
            catch
            {
                return -1;
            }

        }

        public int ExcuteSQL(string mySQL)
        {
            SqlCommand myCommand = new SqlCommand(mySQL, this.dataConnection);

            try
            {
                this.open();
                int numRow = 0;
                numRow = myCommand.ExecuteNonQuery();
                this.close();
                return numRow;
            }
            catch
            {
                return -1;
            }
        }

    }
}
